package com.hanhai.zrb.api.biz.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hanhai.common.bizInterface.ChangeNotifyUtil;
import com.hanhai.common.file.fastdfs.service.IStorageClientService;
import com.hanhai.zrb.api.biz.dao.mybatis.CityInfoMapper;
import com.hanhai.zrb.api.biz.dao.mybatis.FundMapper;
import com.hanhai.zrb.api.biz.dao.mybatis.IndustryMapper;
import com.hanhai.zrb.api.biz.dao.mybatis.IntentionMapper;
import com.hanhai.zrb.api.biz.dao.mybatis.PhotoDao;
import com.hanhai.zrb.api.biz.dao.mybatis.ProjectMapper;
import com.hanhai.zrb.api.biz.dao.mybatis.SysDictionaryMapper;
import com.hanhai.zrb.api.biz.dao.mybatis.UserStatisticDetailMapper;
import com.hanhai.zrb.api.biz.service.BizMonitorService;
import com.hanhai.zrb.api.biz.service.CommonCounterService;
import com.hanhai.zrb.api.biz.service.MessageSendService;
import com.hanhai.zrb.api.biz.service.ProjectFundSequenceService;
import com.hanhai.zrb.api.biz.service.ProjectService;
import com.hanhai.zrb.api.biz.service.ResourceMatchCacheManager;
import com.hanhai.zrb.api.biz.service.SysDictionaryService;
import com.hanhai.zrb.api.biz.service.UserService;
import com.hanhai.zrb.api.mongodb.ProjectDetailClient;
import com.hanhai.zrb.api.mongodb.ProjectDetailMongodbClient;
import com.hanhai.zrb.api.mongodb.SpringContextUtil;
import com.hanhai.zrb.api.solr.SolrHelper;
import com.hanhai.zrb.api.solr.SolrService;
import com.hanhai.zrb.model.common.CommonCounterKey;
import com.hanhai.zrb.model.common.SysDictionary;
import com.hanhai.zrb.model.fund.Fund;
import com.hanhai.zrb.model.intention.Intention;
import com.hanhai.zrb.model.photo.Photo;
import com.hanhai.zrb.model.photo.PhotoVo;
import com.hanhai.zrb.model.project.CityInfo;
import com.hanhai.zrb.model.project.Industry;
import com.hanhai.zrb.model.project.Project;
import com.hanhai.zrb.model.project.ProjectDetail;
import com.hanhai.zrb.model.project.ProjectDetailSolrDto;
import com.hanhai.zrb.model.project.ProjectExample;
import com.hanhai.zrb.model.project.ProjectSolrDto;
import com.hanhai.zrb.model.resourcematch.ResourceMatchTypeEnum;
import com.hanhai.zrb.model.user.User;
import com.hanhai.zrb.model.user.UserStatisticDetail;

@Service
public class ProjectServiceImpl implements ProjectService {

	@Autowired
	private ProjectMapper projectMapper;
	@Autowired
	private FundMapper fundMapper;
	@Resource
	private PhotoDao photoDao;

	private ProjectDetailClient projectDetailClient = new ProjectDetailClient();

	@Autowired
	private SysDictionaryMapper sysDictionaryMapper;

	@Autowired
	private IndustryMapper industryMapper;

	@Autowired
	private IntentionMapper intentionMapper;

	@Autowired
	private CityInfoMapper cityInfoMapper;

	@Resource
	private ResourceMatchCacheManager resourceMatchCacheManager;
	
	@Resource
	private UserService userService;

	@Resource
	private MessageSendService messageSendService;
	
	@Resource
	private SysDictionaryService sysDictionaryService;

	@Resource
	private UserStatisticDetailMapper userStatisticDetailMapper;

	@Resource
	private CommonCounterService commonCounterService;

	@Resource
	private SolrService solrService;

	@Autowired
	private IStorageClientService storageClientService;

	@Resource
	private ProjectFundSequenceService projectFundNoService;

	private Logger logger = Logger.getLogger(getClass());
    private static Logger LOG = Logger.getLogger(ProjectServiceImpl.class);
	/**
	 * 如果项目认证状态变化，就发出通知，监听此事件的对象能够出发通知
	 * 
	 * @param projectId
	 */
	private void projectAuthStatusNotify(Long projectId) {
		ChangeNotifyUtil.notify(ProjectService.notifySubject_change_authstatus,
				projectId);
	}

	@Override
	public PageInfo listAll(ProjectDetail projectDetail, int pageNum,
			int pageSize) {
		PageHelper.startPage(pageNum, pageSize, true);
		ProjectExample cExample = new ProjectExample();
		cExample.setOrderByClause("id desc");
		ProjectExample.Criteria cCra = cExample.createCriteria();
		cCra.andProjectStatusNotEqualTo((short) 0);
		if (null != projectDetail) {
			if (null != projectDetail.getProjectStatus()) {
				cCra.andProjectStatusEqualTo(projectDetail.getProjectStatus());
			}

			if (null != projectDetail.getIndustryId()) {
				cCra.andIndustryIdEqualTo(projectDetail.getIndustryId());
			}

			if (null != projectDetail.getProvincePostcode()
					&& !"".equals(projectDetail.getProvincePostcode())) {
				cCra.andProvincePostcodeEqualTo(projectDetail
						.getProvincePostcode());
			}

			if (null != projectDetail.getProjectStatus()) {
				cCra.andProjectStatusEqualTo(projectDetail.getProjectStatus());
			}

			if (null != projectDetail.getAuth()) {
				cCra.andAuthEqualTo(projectDetail.getAuth());
			}

			if (null != projectDetail.getMode()) {
				cCra.andModeEqualTo(projectDetail.getMode());
			}

			SimpleDateFormat simpledateformat = new SimpleDateFormat(
					"yyyy-MM-dd hh:mm:ss");
			if (null != projectDetail.getQryStartDate()
					&& !"".equals(projectDetail.getQryStartDate())) {
				try {
					Date qryStartDate = simpledateformat.parse(projectDetail
							.getQryStartDate() + " 00:00:00");
					cCra.andPushtimeGreaterThanOrEqualTo(qryStartDate);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}

			if (null != projectDetail.getQryEndDate()
					&& !"".equals(projectDetail.getQryEndDate())) {
				try {
					Date qryEndDate = simpledateformat.parse(projectDetail
							.getQryEndDate() + " 23:59:59");
					cCra.andPushtimeLessThanOrEqualTo(qryEndDate);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}

			if (null != projectDetail.getQryKeyWord()
					&& !"".equals(projectDetail.getQryKeyWord())) {
				cExample.or().andProjectNameLike(
						"%" + projectDetail.getQryKeyWord() + "%");

				cExample.or().andPusherLike(
						"%" + projectDetail.getQryKeyWord() + "%");

				cExample.or().andProjectNoLike(
						"%" + projectDetail.getQryKeyWord() + "%");

			}

		}
		List<Project> page = projectMapper.selectByExample(cExample);
		List<ProjectDetail> projectDetailLs = null;
		if (null != page) {
			SimpleDateFormat simpledateformat = new SimpleDateFormat(
					"yyyy-MM-dd");
			projectDetailLs = new ArrayList<ProjectDetail>();
			List<SysDictionary> dicLs = sysDictionaryMapper.selectAll();
			List<Industry> indLs = industryMapper.selectAll();
			List<Long> idList = new ArrayList<Long>();
			for (Project p : page) {
				if (null != p.getPushtime()) {
					p.setPushtimeStr(simpledateformat.format(p.getPushtime()));
				}

				if (null != p.getInsertTime()) {
					p.setInsertTimeStr(simpledateformat.format(p
							.getInsertTime()));
				}

				if (null != p.getIntentionId()) {
					Intention intention = intentionMapper.selectByPrimaryKey(p
							.getIntentionId());
					if (null != intention) {
						p.setIntentionStr(intention.getIntro());
					}
				}

				if (null != p.getPusher() && !"".equals(p.getPusher())) {
					User user = userService.findById(Long.parseLong(p.getPusher()));
					if (null != user) {
						p.setPusherName(user.getRealname());
					}
				}

				if (null != p.getMode()) {
					for (SysDictionary s : dicLs) {
						if (s.getItemCode().equals(String.valueOf(p.getMode()))) {
							p.setModeStr(s.getItemName());
							break;
						}
					}
				}

				if (null != p.getProjectStatus()) {
					for (SysDictionary s : dicLs) {
						if (s.getItemCode().equals(
								String.valueOf(p.getProjectStatus()))) {
							p.setProjectStatusStr(s.getItemName());
							break;
						}
					}
				}

				if (null != p.getAuth()) {
					for (SysDictionary s : dicLs) {
						if (s.getItemCode().equals(String.valueOf(p.getAuth()))) {
							p.setAuthStr(s.getItemName());
							break;
						}
					}
				}

				if (null != p.getIndustryId()) {
					for (Industry i : indLs) {
						if (i.getId() == p.getIndustryId()) {
							p.setIndustryStr(i.getIndustryName());
							break;
						}
					}
				}

				idList.add(p.getId());
			}

			List<ProjectDetail> tempList = projectDetailClient
					.getProjectInfoBasic(idList);
			Map<Long, ProjectDetail> map = ProjectDetailMongodbClient
					.convertListToMap(tempList);
			for (Project project : page) {
				ProjectDetail detail = null != map.get(project.getId()) ? map
						.get(project.getId()) : new ProjectDetail();
				BeanUtils.copyProperties(project, detail);
				projectDetailLs.add(detail);
			}
		}

		PageInfo pageInfo = new PageInfo(page);
		pageInfo.setList(projectDetailLs);

		return pageInfo;
	}

	@Override
	public PageInfo listAllFromSolr(ProjectDetail projectDetail, int pageNum,
			int pageSize) {
		SolrHelper<ProjectSolrDto> solrHelper = new SolrHelper<ProjectSolrDto>(
				solrService.getSolrProjectUrl());
		solrHelper.andNotEquals("projectStatus", "0");

		if (null != projectDetail) {
			if (null != projectDetail.getProjectStatus()) {
				solrHelper.andEquals("projectStatus",
						String.valueOf(projectDetail.getProjectStatus()));
			}

			if (null != projectDetail.getIndustryId()) {
				solrHelper.andEquals("industryId",
						String.valueOf(projectDetail.getIndustryId()));
			}

			if (null != projectDetail.getProvincePostcode()
					&& !"".equals(projectDetail.getProvincePostcode())) {
				solrHelper.andEquals("provincePostcode",
						projectDetail.getProvincePostcode());
			}

			if (null != projectDetail.getProjectStatus()) {
				solrHelper.andEquals("projectStatus",
						String.valueOf(projectDetail.getProjectStatus()));
			}

			if (null != projectDetail.getAuth()) {
				solrHelper.andEquals("auth",
						String.valueOf(projectDetail.getAuth()));
			}

			if (null != projectDetail.getMode()) {
				solrHelper.andEquals("mode",
						String.valueOf(projectDetail.getMode()));
			}
			if(projectDetail.getUserId() != null){
				solrHelper.andEquals("userId", projectDetail.getUserId()+"");
			}

			SimpleDateFormat simpledateformat = new SimpleDateFormat(
					"yyyy-MM-dd hh:mm:ss");
			if (null != projectDetail.getQryStartDate()
					&& !"".equals(projectDetail.getQryStartDate())) {
				try {
					Date qryStartDate = simpledateformat.parse(projectDetail
							.getQryStartDate() + " 00:00:00");
					solrHelper.andDateGreaterThanOrEqualTo("pushtime",
							qryStartDate);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}

			if (null != projectDetail.getQryEndDate()
					&& !"".equals(projectDetail.getQryEndDate())) {
				try {
					Date qryEndDate = simpledateformat.parse(projectDetail
							.getQryEndDate() + " 23:59:59");
					solrHelper.andDateLessThanOrEqualTo("pushtime", qryEndDate);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}

			if (null != projectDetail.getQryKeyWord()
					&& !"".equals(projectDetail.getQryKeyWord())) {
				solrHelper.andStartSub();
				solrHelper
						.andLike("projectName", projectDetail.getQryKeyWord());
				List<String> strUids = userService.findUidByRealNameOrUmobile(projectDetail.getQryKeyWord());
				if(CollectionUtils.isNotEmpty(strUids)){
					solrHelper.orIn("pusher", strUids);
				}				
				solrHelper.orLike("projectNo", projectDetail.getQryKeyWord());
				solrHelper.endSub();
			}

		}
		List<ProjectSolrDto> page = solrHelper.execQuery(pageNum, pageSize,
				"id desc", ProjectSolrDto.class);
		List<ProjectDetailSolrDto> projectDetailSolrDtoLs = null;
		if (null != page) {
			SimpleDateFormat simpledateformat = new SimpleDateFormat(
					"yyyy-MM-dd");
			projectDetailSolrDtoLs = new ArrayList<ProjectDetailSolrDto>();
			List<Long> idList = new ArrayList<Long>();
			Set<Long> uidIdSet = new HashSet<Long>();
			for (ProjectSolrDto p : page) {
				if (null != p.getPushtime()) {
					p.setPushtimeStr(simpledateformat.format(p.getPushtime()));
				}

				if (null != p.getInsertTime()) {
					p.setInsertTimeStr(simpledateformat.format(p
							.getInsertTime()));
				}

				idList.add(p.getId());
				uidIdSet.add(Long.valueOf(p.getPusher()));
			}

			List<ProjectDetail> tempList = projectDetailClient
					.getProjectInfoBasic(idList);
			Map<Long, ProjectDetail> map = ProjectDetailMongodbClient
					.convertListToMap(tempList);
			Map<Long,User> userMap = userService.findUserMapByUids(new ArrayList<Long>(uidIdSet));
			for (ProjectSolrDto project : page) {
				ProjectDetail detail = null != map.get(project.getId()) ? map
						.get(project.getId()) : new ProjectDetail();
				String uid = project.getPusher();
				if(StringUtils.isNoneBlank(uid)){
					User user = userMap.get(Long.valueOf(uid));
					if(user !=null){
						project.setPusherName(user.getRealname());
						project.setPhone(user.getUmobile());
					}
				}
				
				ProjectDetailSolrDto projectDetailSolrDto = new ProjectDetailSolrDto();

				BeanUtils.copyProperties(detail, projectDetailSolrDto);
				BeanUtils.copyProperties(project, projectDetailSolrDto);
				//projectDetailSolrDto.setPusher(userMap);
				projectDetailSolrDtoLs.add(projectDetailSolrDto);
			}
		}

		PageInfo pageInfo = new PageInfo(page);
		pageInfo.setList(projectDetailSolrDtoLs);

		return pageInfo;
	}

	@Override
	public void add(ProjectDetail projectDetail) {
		projectDetail.setProjectStatus((short) 202);// 0删除202待审核203发布204撤销
		projectDetail.setInsertTime(new Date());
		String projectNo=projectFundNoService.getNextProjectSequence();
		projectDetail.setProjectNo(projectNo);
		/*
		 * if(null != customerinfo.getLinetimeStr() &&
		 * !"".equals(customerinfo.getLinetimeStr())){ SimpleDateFormat
		 * simpledateformat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); try {
		 * customerinfo
		 * .setLinetime(simpledateformat.parse(customerinfo.getLinetimeStr()));
		 * } catch (ParseException e) { e.printStackTrace(); } }
		 */

		if (null != projectDetail.getProvincePostcode()) {
			CityInfo cityInfo = cityInfoMapper.selectByPostcode(projectDetail
					.getProvincePostcode());
			if (null != cityInfo) {
				projectDetail.setProvince(cityInfo.getCityName());
			}
		}

		projectMapper.insert(projectDetail);
		// 同步solr
		solrService.synProject(projectDetail.getId());

		// 存hbase
		// long id = projectDetail.getId();
		// projectDetailHbaseClient.insertProjectDetail(projectDetail);
		projectDetailClient.add(projectDetail);
	}

	@Override
	public void update(ProjectDetail projectDetail) {
		ProjectDetail oldProjectDetail = this
				.qryProjectDetailById(projectDetail.getId());
		if (null != projectDetail.getProvincePostcode()) {
			CityInfo cityInfo = cityInfoMapper.selectByPostcode(projectDetail
					.getProvincePostcode());
			if (null != cityInfo) {
				projectDetail.setProvince(cityInfo.getCityName());
			}
		}

		projectDetail.setUpdateTime(new Date());
		// projectDetail.setProjectStatus((short) 202);// 0删除202待审核203发布204撤销
		checkIfPublish(projectDetail, oldProjectDetail);
		projectMapper.updateByPrimaryKeySelective(projectDetail);
		// 存hbase
		// long id = projectDetail.getId();
		// projectDetailHbaseClient.insertProjectDetail(projectDetail);
		projectDetailClient.update(projectDetail);

		// 同步solr
		solrService.synProject(projectDetail.getId());
		if (203 == oldProjectDetail.getProjectStatus()
				&& null != oldProjectDetail.getIntentionId()) {// 如果原来是发布状态
																// 现在修改变成审核状态了
			projectAuthStatusNotify(projectDetail.getId());
		}

	}

	// 发布状态下，6个字段不会被更新，前端验证了，后端也需要验证
	// 项目标题、认证状态， 融资方式、金额、所属行业、 所属省份
	private void checkIfPublish(ProjectDetail projectDetail,
			ProjectDetail oldProjectDetail) {
		if (projectDetail == null || oldProjectDetail == null) {
			logger.error("projectDetail or oldProjectDetail is null~");
			return;
		}
		//原项目状态不是203发布
		Short status=203;
		if (!oldProjectDetail.getProjectStatus().equals(status)) {
			return;
		}
		//发布检查6个字段,如果最新的6个字段不为null，但是和原来的却不同，那么肯定是出了问题
		String oldProjectName=oldProjectDetail.getProjectName();
		Integer oldAuth=oldProjectDetail.getAuth();
		Integer oldMode =oldProjectDetail.getMode();
		BigDecimal oldTotal=oldProjectDetail.getTotal();
		Integer oldIndustryId=oldProjectDetail.getIndustryId();
		String oldProvincePostcode=oldProjectDetail.getProvincePostcode();

		String projectName=projectDetail.getProjectName();
		Integer auth=projectDetail.getAuth();
		Integer mode=projectDetail.getMode();
		BigDecimal total=projectDetail.getTotal();
		Integer industryId=projectDetail.getIndustryId();
		String provincePostCode=projectDetail.getProvincePostcode();
		if(projectName!= null && !projectName.equals(oldProjectName)){
			logger.error("The projectName is not null,and not equals with the old value.");
		}
		if(auth != null && !auth.equals(oldAuth)){
			logger.error("The auth is not null,and not equals with the old value.");
		}
		if(mode != null && !mode.equals(mode)){
			logger.error("The mode is not null,and not equals with the old value.");
		}
		if(total!= null && !total.equals(oldTotal)){
			logger.error("The total is not null,and not equals with the old value.");
		}
		if(industryId != null && !industryId.equals(oldIndustryId)){
			logger.error("The industryId is not null,and not equals with the old value.");
		}
		if(provincePostCode!= null && !provincePostCode.equals(oldProvincePostcode)){
			logger.error("The provincePostCode is not null,and not equals with the old value.");
		}
		//6个字段使用原来的，确保不被更新
		projectDetail.setProjectName(oldProjectName);
		projectDetail.setAuth(oldAuth);
		projectDetail.setMode(oldMode);
		projectDetail.setTotal(oldTotal);
		projectDetail.setIndustryId(oldIndustryId);
		projectDetail.setProvincePostcode(oldProvincePostcode);
	}

	@Override
	public void delete(long id) {
		ProjectDetail oldProjectDetail = this.qryProjectDetailById(id);

		ProjectDetail projectDetail = new ProjectDetail();
		projectDetail.setId(id);
		projectDetail.setProjectStatus((short) 0);// 0删除202待审核203发布204撤销
		projectMapper.updateByPrimaryKeySelective(projectDetail);
		// 同步solr
		solrService.synProject(projectDetail.getId());

		if (203 == oldProjectDetail.getProjectStatus()
				&& null != oldProjectDetail.getIntentionId()) {// 如果原来是发布状态
																// 现在删除了
			projectAuthStatusNotify(id);
		}

	}

	@Override
	public Map<Long, Project> queryMapByIdList(List<Long> list) {
		List<Project> projectList = this.projectMapper.queryByIdList(list);
		Map<Long, Project> map = new HashMap<Long, Project>();
		for (Project pro : projectList) {
			map.put(pro.getId(), pro);
		}
		return map;
	}

	@Override
	public void audit(long id, short status) {
		ProjectDetail projectDetail = new ProjectDetail();
		projectDetail.setId(id);
		projectDetail.setProjectStatus(status);
		if ((short) 203 == status) {// 发布
			projectDetail.setPushtime(new Date());
		}

		projectMapper.updateByPrimaryKeySelective(projectDetail);
		// 同步solr
		solrService.synProject(projectDetail.getId());
		Project project = projectMapper.selectByPrimaryKey(id);

		Long intentionId = project.getIntentionId();
		if ((short) 203 == project.getProjectStatus() && null != intentionId) { // 通知
			projectAuthStatusNotify(id);
		}
		if ((short) 203 == project.getProjectStatus().shortValue()) {
			if (project.getPusher() != null) {
				BizMonitorService bizMonitor = getBizMonitorService();
				bizMonitor.projectFirstPublish(project);
			}
			String key = ResourceMatchCacheManagerImpl.buildKey(id,ResourceMatchTypeEnum.PROJECT.getCode());
			logger.info("Project publish,Try to delete cache in redis, project id="+id);
			resourceMatchCacheManager.delete(key);
		}
	}

	@Override
	public List<Project> queryPageByOwnerId(String owner, Date pushTime,
			Integer limit, Integer state) {
		PageHelper.startPage(1, limit, true);
		List<Project> page = projectMapper.queryByOwnerId(owner, pushTime,
				state);
		PageInfo pageInfo = new PageInfo(page);
		return pageInfo.getList();
	}

	@Override
	public List<Project> queryByIdList(List<Long> list) {
		return projectMapper.queryByIdList(list);
	}
	
	@Override
	public List<Project> queryByIdsList(List<Long> list) {
		List<Project> queryByIdList = projectMapper.queryByIdList(list);
		if( null!= queryByIdList && !queryByIdList.isEmpty()){
			for (Project project : queryByIdList) {
				//所属行业
				Industry industry = industryMapper.selectByPrimaryKey(project.getIndustryId());
				if( null!= industry && StringUtils.isNotBlank(industry.getIndustryName())){
					project.setIndustryStr(industry.getIndustryName());
				}
				
				//发布人名字
				if(project.getPusher() != null){
					User user = userService.findById(Long.parseLong(project.getPusher()));
					if( user != null && StringUtils.isNotBlank(user.getUname())){
						project.setPusherName(user.getUname());
					}
				}
				
				//融资方式
				if(project.getMode() != null){
					SysDictionary selectByCodemode = sysDictionaryService.getByCodeFromLocalCache( String.valueOf(project.getMode()));
					project.setModeStr(selectByCodemode.getItemName());
				}
				
				//项目状态
				if( 0 != project.getProjectStatus()){
					SysDictionary status = sysDictionaryService.getByCodeFromLocalCache( String.valueOf(project.getProjectStatus()));
					project.setProjectStatusStr(status.getItemName());
				}
				
				//认证状态
				SysDictionary statusd = sysDictionaryService.getByCodeFromLocalCache( String.valueOf(project.getAuth()));
				if( null!= statusd && StringUtils.isNotBlank(statusd.getItemName())){
					project.setAuthStr(statusd.getItemName());
				}
				
				//发布时间
				if( null != project.getPushtime()){
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
					String str = sdf.format(project.getPushtime());
					project.setPushtimeStr(str);
				}
				
			}
		}
		return queryByIdList;
	}

	public Project selectByPrimaryKey(Long id) {
		return projectMapper.selectByPrimaryKey(id);
	}

	@Override
	public ProjectDetail qryProjectDetailById(long id) {

		Project project = projectMapper.selectByPrimaryKey(id);
		if (null != project) {
			if (null != project.getIndustryId()) {
				Industry industry = industryMapper.selectByPrimaryKey(project
						.getIndustryId());
				if (null != industry) {
					project.setIndustryStr(industry.getIndustryName());
				}
			}

			if (null != project.getProjectStatus()) {
				SysDictionary sysDictionary = sysDictionaryMapper
						.selectByCode(String.valueOf(project.getProjectStatus()));
				if (null != sysDictionary) {
					project.setProjectStatusStr(sysDictionary.getItemName());
				}
			}

			if (null != project.getMode()) {
				SysDictionary sysDictionary = sysDictionaryMapper
						.selectByCode(String.valueOf(project.getMode()));
				if (null != sysDictionary) {
					project.setModeStr(sysDictionary.getItemName());
				}
			}

			if (null != project.getAuth()) {
				SysDictionary sysDictionary = sysDictionaryMapper
						.selectByCode(String.valueOf(project.getAuth()));
				if (null != sysDictionary) {
					project.setAuthStr(sysDictionary.getItemName());
				}
			}

			// 获取关注数量
			CommonCounterKey commonCounterKey = new CommonCounterKey();
			commonCounterKey.setMainKey(UserStatisticDetail.Type.pro_col
					.getCountKey());
			commonCounterKey.setSecondaryKey(project.getId().toString());
			project.setAttentionCount(commonCounterService
					.getCurrentCountByKey(commonCounterKey));

			// 获取图片列表
			List<Photo> photoList = photoDao.getPhotoListByProjectId(id);
			project.setPhotoList(photoList);
			project.setPhotoListJson(JSON.toJSONString(photoList));
			ProjectDetail projectDetail;
			// projectDetail = projectDetailHbaseClient.getProjectDetail(id);
			projectDetail = projectDetailClient.get(id);
			if (null == projectDetail) {
				projectDetail = new ProjectDetail();

			}

			BeanUtils.copyProperties(project, projectDetail);

			return projectDetail;

		}

		return null;
	}

	@Override
	public List<Project> listForMobile(Date lastPushTime, int pageSize) {
		PageHelper.startPage(1, pageSize, true);
		ProjectExample cExample = new ProjectExample();
		cExample.setOrderByClause("pushTime desc");
		ProjectExample.Criteria cCra = cExample.createCriteria();
		cCra.andProjectStatusEqualTo((short) 203);
		cCra.andPushtimeLessThan(lastPushTime);

		List<Project> proLs = projectMapper.selectByExample(cExample);
		if (null != proLs && proLs.size() > 0) {
			for (Project project : proLs) {
				String picName = project.getPic();
				if (StringUtils.isNotBlank(picName)) {
					int index = picName.lastIndexOf(".");
					if (index > 0) {
						String smallPicName = picName.substring(0, index)
								+ "_160x120" + picName.substring(index);
						project.setPic(smallPicName);
					}
				}
				if (null != project.getIndustryId()) {
					Industry industry = industryMapper
							.selectByPrimaryKey(project.getIndustryId());
					if (null != industry) {
						project.setIndustryStr(industry.getIndustryName());
						project.setIndustryColor(industry.getColor());
					}
				}

				if (null != project.getProjectStatus()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project
									.getProjectStatus()));
					if (null != sysDictionary) {
						project.setProjectStatusStr(sysDictionary.getItemName());
					}
				}

				if (null != project.getMode()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project.getMode()));
					if (null != sysDictionary) {
						project.setModeStr(sysDictionary.getItemName());
					}
				}

				if (null != project.getAuth()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project.getAuth()));
					if (null != sysDictionary) {
						project.setAuthStr(sysDictionary.getItemName());
					}
				}
			}
		}

		return proLs;
	}

	@Override
	public List<Project> listForMobile(long userId, Date lastPushTime,
			int pageSize) {
		PageHelper.startPage(1, pageSize, true);
		ProjectExample cExample = new ProjectExample();
		cExample.setOrderByClause("pushTime desc");
		ProjectExample.Criteria cCra = cExample.createCriteria();
		cCra.andProjectStatusEqualTo((short) 203);
		cCra.andPusherEqualTo(String.valueOf(userId));
		cCra.andPushtimeLessThan(lastPushTime);

		List<Project> proLs = projectMapper.selectByExample(cExample);
		if (null != proLs && proLs.size() > 0) {
			for (Project project : proLs) {

				String picName = project.getPic();
				if (StringUtils.isNotBlank(picName)) {
					int index = picName.lastIndexOf(".");
					if (index > 0) {
						String smallPicName = picName.substring(0, index)
								+ "_160x120" + picName.substring(index);
						project.setPic(smallPicName);
					}
				}
				if (null != project.getIndustryId()) {
					Industry industry = industryMapper
							.selectByPrimaryKey(project.getIndustryId());
					if (null != industry) {
						project.setIndustryStr(industry.getIndustryName());
						project.setIndustryColor(industry.getColor());
					}
				}

				if (null != project.getProjectStatus()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project
									.getProjectStatus()));
					if (null != sysDictionary) {
						project.setProjectStatusStr(sysDictionary.getItemName());
					}
				}

				if (null != project.getMode()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project.getMode()));
					if (null != sysDictionary) {
						project.setModeStr(sysDictionary.getItemName());
					}
				}

				if (null != project.getAuth()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project.getAuth()));
					if (null != sysDictionary) {
						project.setAuthStr(sysDictionary.getItemName());
					}
				}
			}
		}

		return proLs;
	}

	@Override
	public boolean isBindIntention(long intentionId, long projectId) {
		ProjectExample cExample = new ProjectExample();
		ProjectExample.Criteria cCra = cExample.createCriteria();
		cCra.andProjectStatusNotEqualTo((short) 0);
		cCra.andIntentionIdEqualTo(intentionId);
		if (0 != projectId) {
			cCra.andIdNotEqualTo(projectId);
		}

		List<Project> proLs = projectMapper.selectByExample(cExample);
		if (null != proLs && proLs.size() > 0) {
			return true;
		}

		return false;
	}

	@Override
	public boolean isExsitedProjectNo(String projectNo, long projectId) {
		ProjectExample cExample = new ProjectExample();
		ProjectExample.Criteria cCra = cExample.createCriteria();
		cCra.andProjectStatusNotEqualTo((short) 0);
		cCra.andProjectNoEqualTo(projectNo);
		if (0 != projectId) {
			cCra.andIdNotEqualTo(projectId);
		}

		List<Project> proLs = projectMapper.selectByExample(cExample);
		if (null != proLs && proLs.size() > 0) {
			return true;
		}

		return false;
	}

	@Override
	public void migratePic() {
		logger.info("Start to migrate pic");
		List<Project> projectList = projectMapper.listAll();
		List<Photo> photoList = photoDao.listAll();
		List<Photo> toAddPhotoList = buildPhotoList(projectList, photoList);
		if (CollectionUtils.isNotEmpty(toAddPhotoList)) {
			photoDao.batchAdd(toAddPhotoList);
		}
		logger.info("Migrate pic end,size=" + toAddPhotoList.size());
	}

	private List<Photo> buildPhotoList(List<Project> projectList,
			List<Photo> photoList) {
		List<String> existUrlList = existUrlList(photoList);
		List<Photo> toAddPhotoList = new ArrayList<Photo>();
		if (CollectionUtils.isNotEmpty(projectList)) {
			for (Project project : projectList) {
				String name = project.getPic();
				if (project != null && !existUrlList.contains(name)) {
					Photo photo = new Photo();
					photo.setBizid(project.getId());
					photo.setCover(1);
					photo.setSort(0);
					photo.setUrl(name);
					photo.setName(name);
					photo.setStatus(0);
					photo.setType(1);
					photo.setRemark("");
					toAddPhotoList.add(photo);
				} else {
					logger.error("The project in the projectList is null~");
				}

			}
		}
		return toAddPhotoList;
	}

	private List<String> existUrlList(List<Photo> photoList) {
		List<String> existUrlList = new ArrayList<String>();
		if (CollectionUtils.isNotEmpty(photoList)) {
			for (Photo photo : photoList) {
				if (photo != null) {
					existUrlList.add(photo.getUrl());
				} else {
					logger.error("The photo in the photoList is null~");
				}
			}
		}
		return existUrlList;
	}

	@Override
	public PhotoVo viewPhoto(Long id) {
		PhotoVo photoVo = new PhotoVo();
		photoVo.setProjectId(id);
		Project project = projectMapper.selectByPrimaryKey(id);
		List<Photo> photoList = photoDao.getPhotoListByProjectId(id);
		photoVo.setPhotoList(photoList);
		photoVo.setProject(project);
		return photoVo;
	}

	@Override
	public List<Project> listForIndustryAndPostcode(Date lastPushTime,
			List<Integer> industrysList, List<String> postcode,String mode, int pageSize) {
		PageHelper.startPage(1, pageSize, true);
		ProjectExample cExample = new ProjectExample();
		cExample.setOrderByClause("pushTime desc");
		ProjectExample.Criteria cCra = cExample.createCriteria();
		cCra.andProjectStatusEqualTo((short) 203);
		cCra.andPushtimeLessThan(lastPushTime);
		if (CollectionUtils.isNotEmpty(postcode)) {
			cCra.andProvincePostcodeIn(postcode);
		}
		if (CollectionUtils.isNotEmpty(industrysList)) {

			cCra.andIndustryIdIn(industrysList);
		}
		if(StringUtils.isNumeric(mode)){
			cCra.andModeEqualTo(Integer.valueOf(mode));
		}
		

		List<Project> proLs = projectMapper.selectByExample(cExample);
		if (null != proLs && proLs.size() > 0) {
			for (Project project : proLs) {
				String picName = project.getPic();
				if (StringUtils.isNotBlank(picName)) {
					int index = picName.lastIndexOf(".");
					if (index > 0) {
						String smallPicName = picName.substring(0, index)
								+ "_160x120" + picName.substring(index);
						project.setPic(smallPicName);
					}
				}
				if (null != project.getIndustryId()) {
					Industry industry = industryMapper
							.selectByPrimaryKey(project.getIndustryId());
					if (null != industry) {
						project.setIndustryStr(industry.getIndustryName());
						project.setIndustryColor(industry.getColor());
					}
				}

				if (null != project.getProjectStatus()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project
									.getProjectStatus()));
					if (null != sysDictionary) {
						project.setProjectStatusStr(sysDictionary.getItemName());
					}
				}

				if (null != project.getMode()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project.getMode()));
					if (null != sysDictionary) {
						project.setModeStr(sysDictionary.getItemName());
					}
				}

				if (null != project.getAuth()) {
					SysDictionary sysDictionary = sysDictionaryMapper
							.selectByCode(String.valueOf(project.getAuth()));
					if (null != sysDictionary) {
						project.setAuthStr(sysDictionary.getItemName());
					}
				}
			}
		}

		return proLs;
	}

	public void savePhoto(Long id, List<Photo> list,Integer type) {
		// 这个项目数据库中的图片
		List<Photo> dbList = null ;
		if(type == 1){
			dbList = photoDao.getPhotoListByProjectIdAllStatus(id);
		}else if(type == 2){
			dbList = photoDao.getPhotoListByFundIdAllStatus(id);
		}
		PhotoBean photoBean = handlePhoto(list, dbList);
		handleCover(id, photoBean,type);
		doAdd(id, photoBean.toAdd);
		doUpdate(id, photoBean.toUpdate);
		//每个项目只会删除，这个项目中的临时文件，不会删除其它项目的
		doDelete(id, photoBean.toDelete);
	}

	private void doAdd(Long id, List<Photo> list) {
		if (CollectionUtils.isNotEmpty(list)) {
			handleDefaultField(id, list);
			photoDao.batchAdd(list);
		}
	}

	private void doUpdate(Long id, List<Photo> list) {
		handleDefaultField(id, list);

		// 保存最新的
		if (CollectionUtils.isNotEmpty(list)) {
			for (Photo o : list) {
				photoDao.update(o);
			}
		}
	}

	private void handleDefaultField(Long id, List<Photo> list) {
		if (CollectionUtils.isNotEmpty(list)) {
			// 把项目id放进去
			for (Photo p : list) {
				p.setBizid(id);
				p.setStatus(0);
			}
		}
	}

	private String handleCover(Long id, PhotoBean photoBean,Integer type) {
		List<Photo> list = new ArrayList<Photo>();
		list.addAll(photoBean.toAdd);
		list.addAll(photoBean.toUpdate);

		String cover;
		if (CollectionUtils.isNotEmpty(list)) {
			// 如果不存在主图，选择第1个为主图.
			// 如果存在多个主图，选择最先发现的那个为主图,把其它的设置为“非主图”
			int size = list.size();
			Integer existIndex = -1;
			for (int index = 0; index < size; index++) {
				Photo photo = list.get(index);
				// 确保不会出现多个主图：如果已经找到了主图，把后面的都设置为“非主图”，防止前端验证失败，出现多个主图的情况
				if (existIndex != -1) {
					photo.setCover(0);
				}
				Integer c = photo.getCover();
				// 找到了主图
				if (c != null && c.equals(1)) {
					existIndex = index;
				}
			}
			// 不存在主图
			if (existIndex == -1) {
				list.get(0).setCover(1);
				existIndex = 0;
			}
			// 主图
			cover = list.get(existIndex).getUrl();

		} else {
			// 没有图片，把主图回写为空
			cover = "";
		}
		// 主图回写到project表
		if( type == 1){
			projectMapper.updatePic(id, cover);
		}else if( type == 2){
			fundMapper.updatePic(id, cover);
		}
		return cover;
	}

	private void doDelete(Long id, List<Photo> toDelete) {
		if (CollectionUtils.isNotEmpty(toDelete)) {
			for (Photo o : toDelete) {
				if (o == null || o.getId() == null) {
					logger.error("doDelete photo is null or id is null");
					continue;
				}
				photoDao.delete(o.getId());
				String url = o.getUrl();
				deleteInFastdfs(storageClientService,url);
			}
		}

	}

	public static void deleteInFastdfs(IStorageClientService storageClientService,String url) {
		if (StringUtils.isEmpty(url) || url.length() < 7) {
			LOG.error("doDelete photo,url is invalid~ null or  length < 6");
		}
		if (StringUtils.isNoneBlank(url) && url.length() > 7) {
			// 不要前面的“group1/”
			String path = url.substring(7);
			try {
				LOG.info("Fastdfs,Try to Delete File : " + path);
				storageClientService.deleteFile("group1", path);
			} catch (Exception e) {
				LOG.info("Delete file failed : " + e.getMessage());
				e.printStackTrace();
			}

		}
	}

	// 根据前端photo集合和数据库photo集合，得到需要更新和需要删除的photo集合，不存在需要增加的photo集合
	private PhotoBean handlePhoto(List<Photo> list, List<Photo> dbList) {
		PhotoBean bean = new PhotoBean();
		// 全部删除，什么图片都没有上传
		if (CollectionUtils.isEmpty(list)) {
			bean.toDelete = dbList;
		}
		// 全部增加，一般在第1次
		/*
		 * if (CollectionUtils.isEmpty(dbList)) { bean.toAdd = list; }
		 */
		// 都不为null
		if (list != null && dbList != null) {
			// 交集，肯定不为null，最多是empty,id相同就是共同存在
			List<Photo> commonList = ListUtils.retainAll(list, dbList);

			// 2者交集
			List<Photo> toUpdate = commonList;
			// 数据库中的临时图片，状态需要改为“正常”
			if (CollectionUtils.isNotEmpty(toUpdate)) {
				for (Photo p : toUpdate) {
					p.setStatus(0);
				}
			}

			// 在list，不在dbList中的
			List<Photo> toAdd = new ArrayList<Photo>();
			for (Photo p : list) {
				if (!dbList.contains(p)) {
					toAdd.add(p);
				}
			}
			// 在dbList，不在list中的
			List<Photo> toDelete = new ArrayList<Photo>();
			for (Photo p : dbList) {
				if (!list.contains(p)) {
					toDelete.add(p);
				}
			}
			bean.toAdd = toAdd;
			bean.toUpdate = toUpdate;
			bean.toDelete = toDelete;
		}
		return bean;

	}

	@Override
	public void updateProjectNo(Integer update) {
		List<Project> list = projectMapper.listAll();
		if (CollectionUtils.isEmpty(list)) {
			logger.info("Project list is null");
			return;
		}
		for (Project project : list) {
			String oldProjectNo = project.getProjectNo();
			String newProjectNo = projectFundNoService.getNextProjectSequence();
			if (update != null && update.equals(1)) {
				project.setProjectNo(newProjectNo);
				projectMapper.updateByPrimaryKey(project);
			}
			logger.info("OldProjectNo=" + oldProjectNo + ",NewProjectNo="
					+ newProjectNo);
		}
	}

	@Override
	public void updateFundNo(Integer update) {
		List<Fund> list = fundMapper.listAll();
		if (CollectionUtils.isEmpty(list)) {
			logger.info("Fund list is null");
			return;
		}
		for (Fund fund : list) {
			String oldFundNo = fund.getFundNo();
			String newFundNo = projectFundNoService.getNextFundSequence();
			if (update != null && update.equals(1)) {
				fund.setFundNo(newFundNo);
				fundMapper.updateByPrimaryKey(fund);
			}
			logger.info("oldFundNo=" + oldFundNo + ",newFundNo="
					+ newFundNo);
		}
	}

	@Override
	public int countAllUserProject(Long uid) {
		// TODO Auto-generated method stub
		return projectMapper.countByUid(uid);
	}
	
	private BizMonitorService getBizMonitorService() throws BeansException { 
        return (BizMonitorService) SpringContextUtil.getBean("bizMonitorService"); 
	} 
	
}


class PhotoBean {
	// 将要删除的，通常是数据库中的
	public List<Photo> toDelete;
	// 将要更新的，都在数据库中，部分最新内容来源于web前端
	public List<Photo> toUpdate;
	// 将要增加的，由于上传图片的时候都已经插入了，这个时候可以忽略了，但是存在增加一条记录，但不上传图片的情况
	public List<Photo> toAdd;
}